<?php
/**
 * XmuSlh, web platform of Student Association Federation of Xiamen University
 * 
 * Rewritting one or some pages of StatusNet. 
 * To get the original version, please visit <http://status.net/>.
 * 
 * StatusNet, the distributed open-source microblogging tool
 * 
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * The web entrance. index.php is not only a php page, but also
 * interpret the path coming from the browser!
 * What a fancy thing!
 * 
 * 整个网站的入口, 带有路径解析与路由功能!
 * 
 * @author		ytukie <ytukie@gmail.com>
 * @version		0.4
 * 
 * 0.2)  Fixes some T_ODO and F_IXME.
 * 0.3)  Continue fixing.
 * 		 a) Caculates the excuting time.
 * 0.4)  Hiding the index.php, some changes in slh_get_path.
 */

$_startTime = microtime(true);

// Entrance flag definition.
define('XMUSLH', true);
// The based installation directory.
define('INSTALLDIR', dirname(__FILE__));

// XmuSlh only.
if ( !defined('XMUSLH')) { exit(1); }

// Requirements!
require_once INSTALLDIR . '/lib/slh_init.php';
require_once INSTALLDIR . '/lib/slh_util.php';
require_once INSTALLDIR . '/lib/slh_clientexception.php';
require_once INSTALLDIR . '/lib/slh_serverexception.php';

require_once INSTALLDIR . '/actions/slh_clienterror.php';
require_once INSTALLDIR . '/actions/slh_servererror.php';


/**
 * The method to get the path on the browser.
 * 
 * @param array		$req			$_REQUEST
 */
function slh_get_path($req)
{
	if (array_key_exists('PATH_INFO', $_SERVER)) {
		$path = $_SERVER['PATH_INFO'];
		$script = $_SERVER['SCRIPT_NAME'];
		
		if (substr($path, 0, mb_strlen($script)) == $script) {
			return substr($path, mb_strlen($script));
		} else {
			return $path;
		}
	} else {
		if ((slh_config('site', 'fancy') && array_key_exists('REDIRECT_URL', $_SERVER))) {
			return $_SERVER['REDIRECT_URL'];
	    }
	}
}

/**
 * Handles the error from PEAR!
 * logs and then displays error messages from PEAR!
 */
function handle_error($error)
{
	if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) {
		return;
	}
	
	// Write into the logs file.
	$logmsg = "PEAR error: " . $error->getMessage();
	$logmsg .= " : " . $error->getDebugInfo();
	$logmsg = str_replace("\n", " ", $logmsg);
	slh_log(LOG_ERR, $logmsg);
	
    if ($error instanceof DB_DataObject_Error
        || $error instanceof DB_Error
    ) {
        $msg = sprintf(
            '数据库发生了一些奇怪的错误,如果您一直碰到这些问题,'.
            '请尝试联系我们的管理员: %s .',
            'xmuslh#qq.com'
        );
    } else {
        $msg =
        	'系统出现了严重的故障,请查看日志修复问题!';
    }

	// Log the errors, but just show some instructions.
	ServerErrorAction::show($msg);
}

/** 
 * Main entrance.
 */
function slh_main()
{
	// Get the current url!
	$_SERVER['REDIRECT_URL'] = preg_replace("/\?.+$/", "", $_SERVER['REQUEST_URI']);
	
	// Global declarations.
	global $user, $action;
	
	if ( !checkConfig()) {
		ServerErrorAction::show('没有找到配置文件唉.');
	}
	
	// For database errors
    PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'handle_error');
	
	/*
	 * Get the path and do routing.
	 * To get the '/groups', '/notice', etc.
	 * 
	 * URL:		http://localhost/StatusNet/statusnet-0.9.7fix1/index.php/groups
	 * $path:	/groups
	 */
	$path = slh_get_path($_REQUEST);
	$router = Router::get();
	$args = $router->map($path);
	
	if ( !$args) {
    	ClientErrorAction::show('没有找到相关的页面哦.');
    }

    if (is_array($args)) {
		$args = array_merge($args, $_REQUEST);
    }
	//Generate an action.
	$action = $args['action'];

	// Illegal action.
	if ( !$action || !preg_match('/^[a-zA-Z0-9_-]*$/', $action)) {
        slh_redirect(slh_action2url('publicnews'));
        return;
    }
    
	// Check if closing or being private.
	if (slh_config('site', 'closed')) {
		ServerErrorAction::show('网站当前维护升级中...');
	}

    // Generate an action class.
    $action_class = ucfirst($action) . 'Action';
    
    // Validates the class.
    if ( !class_exists($action_class)) {
    	ClientErrorAction::show('没有找到相关的页面哦!');
    } else {
    	// Load the specific action.
    	$action_obj = new $action_class();
    	// Do the execution via such action mapping.
    	try {
    		if ($action_obj->prepare($args)) {
    			$action_obj->handle($args);
    		} else {
    			ClientErrorAction::show('亲啊,没有登录或者参数不正确?.非法权限操作.');
    		}
    	} catch (ClientException $cex) {
    		ClientErrorAction::show($cex->getMessage());
    	} catch (ServerException $sex) {
    		ServerErrorAction::show($sex->getMessage());
    	} catch (Exception $e) {
    		ClientErrorAction::show('非常规异常:' . $e->getMessage());
    	}
    }
}

// Go!
slh_main();